from flask import Flask, jsonify, request, render_template, send_file, send_from_directory
from ticktock import Ticktock
from miaoshou import ms_login, search_ms_products
from marketing import Marketing
from token_manager import TokenManager, init_token_routes
import math
from functools import wraps


app = Flask(__name__, static_folder='templates', static_url_path='')

# 定义版本号
VERSION = "1.1.6"

# 初始化token管理器
token_manager = TokenManager()
init_token_routes(app, token_manager)

def require_token(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        token = request.headers.get('Authorization')
        if not token:
            return jsonify({
                'code': 401,
                'msg': '未提供认证授权码'
            }), 401
        
        # 验证token
        if not token_manager.verify_token(token):
            return jsonify({
                'code': 401,
                'msg': '授权码无效或已过期'
            }), 401
            
        return f(*args, **kwargs)
    return decorated_function

# 自定义异常类
class APIException(Exception):
    def __init__(self, message="服务器内部错误", code=500):
        self.message = message
        self.code = code
        super().__init__(self.message)

# 全局异常处理
@app.errorhandler(Exception)
def handle_exception(e):
    import traceback
    # 打印完整的堆栈信息到控制台
    print("发生异常:")
    print(traceback.format_exc())
    
    if isinstance(e, APIException):
        response = {
            'code': e.code,
            'msg': e.message
        }
    else:
        response = {
            'code': 500,
            'msg': str(e)
        }
    return jsonify(response), response['code']


@app.route('/images/<path:filename>')
def images(filename):
    return send_from_directory('images', filename)

@app.route('/configs', methods=['GET'])
@require_token
def get_config():
    from config import load_config
    session_id = request.args.get('session_id')
    ticktock = Ticktock(session_id)
    shop_list = ticktock.get_shop_list()
    shops = {shop['shop_region']: shop for shop in shop_list}

    result = {}
    
    for country in shops:
        shop = shops[country]
        try:
            config = load_config(country)
        except:
            config = {}
        result[country] = {
            'shop': shop,
            'config': config
        }
            
    return jsonify({
        'code': 0,
        'data': result
    })

@app.route('/configs/<country>', methods=['POST'])
@require_token
def save_country_config(country):
    from config import save_config
    
    try:
        config = request.get_json()
        save_config(country, config)
        return jsonify({
            'code': 0,
            'msg': '保存成功'
        })
    except Exception as e:
        return jsonify({
            'code': 1, 
            'msg': f'保存失败: {str(e)}'
        })

@app.route('/')
def index():
    return render_template('index.html', version=VERSION)

@app.route('/ms_login', methods=['POST'])
def miaoshou_login():
    data = request.get_json()
    username = data.get('username')
    password = data.get('password')
    mserp, token = ms_login(username, password)
    return jsonify({
        'code': 0,
        'data': {
            'token': token,
            'mserp': mserp
        }
    })

@app.route('/products', methods=['GET'])
@require_token
def get_products():
    session_id = request.args.get('session_id')
    ms_login_token = request.args.get('ms_login_token')
    mserp = request.args.get('mserp')
    shop_id = request.args.get('shop_id')
    page = int(request.args.get('page', 1))
    limit = int(request.args.get('limit', 1000))
    
    # 获取TikTok商品列表
    tt_products = Ticktock(session_id).search_tt_products(shop_id, page, limit)
    
    # 获取秒手源数据
    ms_products = search_ms_products(ms_login_token, mserp, tt_products.keys())
    
    result = []
    coupon_amount = 0
    for product_id, product in tt_products.items():
        ms_product = ms_products.get(product_id, {})
        min_price = min([sku['sale_price'] for sku in product.get('skus', [])])
        max_price = max([sku['sale_price'] for sku in product.get('skus', [])])
        # 从skus中找出is_promote_sku为true的sku的价格作为promote_price
        promote_price = None
        for sku in product.get('skus', []):
            if sku.get('is_promote_sku', False):
                promote_price = sku.get('sale_price')
                break
        exist_discount = product.get('exist_discount', False)
        if exist_discount:
            continue
        if promote_price:
            this_coupon_amount = math.ceil(promote_price * 0.2)
            coupon_amount = max(coupon_amount, this_coupon_amount)
        result.append({
            'product_id': product_id,
            'global_item_id': ms_product.get('globalItemId', ''),
            'exist_discount': exist_discount,
            'skus': product.get('skus', []),
            'source': ms_product.get('source', ''),
            'source_item_id': ms_product.get('sourceItemId', ''),
            'source_url': ms_product.get('sourceItemUrl', ''),
            'thumbnail': ms_product.get('thumbnail', ''),
            'min_price': min_price,
            'max_price': max_price,
            'promote_price': promote_price
        })
        
    return jsonify({
        'code': 0,
        'data': result,
        'coupon_amount': coupon_amount
    })

@app.route('/marketing_preview', methods=['POST'])
@require_token
def marketing_preview():
    session_id = request.args.get('session_id')
    data = request.get_json()
    country = data.get('country')
    shop_id = data.get('shop_id')
    product = data.get('product', {})
    coupon_amount = data.get('coupon_amount', 0)
    marketing = Marketing(session_id, country, shop_id)
    product = marketing.apply_marketing_plan(product, coupon_amount)
    return jsonify({
        'code': 0,
        'data': product
    })

@app.route('/download_kill_config', methods=['POST'])
@require_token
def download_kill_config():
    from io import BytesIO
    import xlsxwriter
    
    # 创建一个内存中的Excel文件
    output = BytesIO()
    workbook = xlsxwriter.Workbook(output)
    worksheet = workbook.add_worksheet()
    
    # 添加表头
    headers = [
        '商品id（必填）', 
        'SKU_id（必填）', 
        """一口价（必填）
1、0<交易价格≤30天最低价
2、促销价格<销售价格""",
        """总量限购（非必填）
1、总量限购≤库存
2、不填写则代表不限制""",
        """单人限购（非必填）
1、1≤单人限购≤99
2、不填写则代表不限制"""
    ]
    for col, header in enumerate(headers):
        worksheet.write(0, col, header)

    session_id = request.args.get('session_id')
    data = request.get_json()
    country = data.get('country')
    shop_id = data.get('shop_id')
    products = data.get('products', {})
    coupon_amount = data.get('coupon_amount', 0)
    marketing = Marketing(session_id, country, shop_id)
    
    row = 1
    for product in products:
        product = marketing.apply_marketing_plan(product, coupon_amount)
        for sku in product['skus']:
            if 'kill_price' in sku:
                worksheet.write(row, 0, product['product_id'])
                worksheet.write(row, 1, sku['sku_id'])
                worksheet.write(row, 2, sku['kill_price'])
                row += 1
    
    workbook.close()
    output.seek(0)
    
    return send_file(
        output,
        mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        as_attachment=True,
        download_name='秒杀配置.xlsx'
    )

@app.route('/download_discount_config', methods=['POST'])
@require_token
def download_discount_config():
    from io import BytesIO
    import xlsxwriter
    
    # 创建一个内存中的Excel文件
    output = BytesIO()
    workbook = xlsxwriter.Workbook(output)
    worksheet = workbook.add_worksheet()
    
    # 添加表头
    headers = [
        '商品id（必填）', 
        'SKU_id（必填）', 
        '折扣（必填）',
        """总量限购（非必填）
1、总量限购≤库存
2、不填写则代表不限制""",
        """单人限购（非必填）
1、1≤单人限购≤99
2、不填写则代表不限制"""
    ]
    for col, header in enumerate(headers):
        worksheet.write(0, col, header)
    
    session_id = request.args.get('session_id')
    data = request.get_json()
    country = data.get('country')
    shop_id = data.get('shop_id')
    products = data.get('products', [])  # 修改默认值为空列表
    coupon_amount = data.get('coupon_amount', 0)
    marketing = Marketing(session_id, country, shop_id)
    
    row = 1
    for product in products:
        product = marketing.apply_marketing_plan(product, coupon_amount)
        for sku in product['skus']:
            if 'discount_rate' in sku:
                worksheet.write(row, 0, product['product_id'])
                worksheet.write(row, 1, sku['sku_id'])
                worksheet.write(row, 2, sku['discount_rate'])
                row += 1

    workbook.close()
    output.seek(0)
    
    return send_file(
        output,
        mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        as_attachment=True,
        download_name='折扣配置.xlsx'
    )

if __name__ == '__main__':
    app.run(debug=True, port=5001)
